home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / Macintosh Tracker 1.1 Source / Tracker Server Folder / altered_audio.c < prev    next >
Text File  |  1993-05-18  |  7KB  |  284 lines

  1. /* audio.c */
  2.  
  3. /* $Id: audio.c,v 3.6 1992/11/27 10:29:00 espie Exp espie $
  4.  * $Log: audio.c,v $
  5.  * Revision 3.6  1992/11/27  10:29:00  espie
  6.  * General cleanup
  7.  *
  8.  * Revision 3.5  1992/11/24  10:51:19  espie
  9.  * Optimized output and fixed up some details.
  10.  * Unrolled code for oversample = 1 to be more efficient at
  11.  * higher frequency (since a high frequency is better than
  12.  * a higher oversample).
  13.  *
  14.  * Revision 3.4  1992/11/23  17:18:59  espie
  15.  * *** empty log message ***
  16.  *
  17.  * Revision 3.3  1992/11/23  10:12:23  espie
  18.  * Fixed up BIG bug.
  19.  *
  20.  * Revision 3.2  1992/11/20  14:53:32  espie
  21.  * Added finetune.
  22.  *
  23.  * Revision 3.1  1992/11/19  20:44:47  espie
  24.  * Protracker commands.
  25.  *
  26.  * Revision 3.0  1992/11/18  16:08:05  espie
  27.  * New release.
  28.  *
  29.  * Revision 2.14  1992/11/06  19:31:53  espie
  30.  * Fixed missing parameter type.
  31.  * fix_xxx for better speed.
  32.  * set_volume.
  33.  * Added possibility to get back to MONO for the sgi.
  34.  * Added stereo capabilities to the indigo version.
  35.  * Minor bug: a SAMPLE_FAULT is a minor error,
  36.  * we should first check that there was no other
  37.  * error before setting it.
  38.  * New resample function coming from the player.
  39.  * Added more notes.
  40.  *
  41.  * Revision 2.1  1991/11/17  23:07:58  espie
  42.  * Just computes some frequency-related parameters.
  43.  *
  44.  *
  45.  */
  46.  
  47. #include <math.h>
  48. #include <malloc.h>
  49. #include <stdio.h>
  50.  
  51. #include "defs.h"
  52. #include "extern.h"
  53. #include "song.h"
  54. #include "channel.h"
  55.      
  56. LOCAL char *id = "$Id: audio.c,v 3.6 1992/11/27 10:29:00 espie Exp espie $";
  57.  
  58. /* Have to get some leeway for vibrato (since we don't bound pitch with
  59.  * vibrato). This is conservative.
  60.  */
  61. #define VIB_MAXDEPTH 150
  62.  
  63.  
  64. #define C fix_to_int(ch->pointer)
  65.  
  66. LOCAL int step_table[MAX_PITCH + VIB_MAXDEPTH];  
  67.                     /* holds the increment for finding the next sampled
  68.                      * byte at a given pitch (see resample() ).
  69.                      */
  70.  
  71. /* creates a table for converting ``amiga'' pitch
  72.  * to a step rate at a given resampling frequency.
  73.  * For accuracy, we don't use floating point, but
  74.  * instead fixed point ( << ACCURACY).
  75.  * IMPORTANT NOTE: we need to make it fit within 32 bits, which
  76.  * must be enough for ACCURACY + log2(max sample length)
  77.  */
  78. LOCAL void create_step_table(oversample, output_fr)
  79. int oversample;     /* we sample oversample i for each byte output */
  80. int output_fr;      /* output frequency */
  81.     {
  82.     double note_fr; /* note frequency (in Hz) */
  83.     double step;
  84.     int pitch;      /* amiga pitch */
  85.  
  86.     step_table[0] = 0;
  87.     for (pitch = 1; pitch < MAX_PITCH + VIB_MAXDEPTH; pitch++)
  88.         {
  89.         note_fr = AMIGA_CLOCKFREQ / pitch;
  90.             /* int_to_fix(1) is the normalizing factor */
  91. /*@ removed oversample since oversampling has been changed to anti-aliasing */
  92.         step = note_fr / output_fr * int_to_fix(1) /* / oversample */;
  93.         step_table[pitch] = (int)step;
  94.         }
  95.     }
  96.          
  97. LOCAL void readjust_pitch(ch)
  98. struct channel *ch;
  99.     {
  100.     int i;
  101.     for (i = 0; i < NUMBER_TRACKS; i++)
  102.         ch[i].step = step_table[ch[i].cpitch];
  103.     }
  104.  
  105. void init_tables(oversample, frequency, chan)
  106. int oversample, frequency;
  107. struct channel *chan;
  108.     {
  109.     create_step_table(oversample, frequency);
  110.     if (chan)
  111.         readjust_pitch(chan);
  112.     }
  113.  
  114. /*@ the original "resample" has been removed */
  115. #if 0
  116.  
  117. /* The playing mechanism itself.
  118.  * According to the current channel automata,
  119.  * we resample the instruments in real time to
  120.  * generate output.
  121.  */
  122. void resample(chan, oversample, number)
  123. struct channel *chan;
  124. int oversample;
  125. int number;
  126.     {
  127.     int i;          /* sample counter */
  128.     int channel;    /* channel counter */
  129.     int sampling;   /* oversample counter */
  130.     SAMPLE sample;  /* sample from the channel */
  131.     int byte[NUMBER_TRACKS];
  132.                     /* recombinations of the various data */
  133.     struct channel *ch;
  134.  
  135.         /* there used to be pointer tests around here, that
  136.          * are no longer needed 
  137.          */
  138.     /* special case oversampling for speedier stuff */
  139.     if (oversample == 1)
  140.         {
  141.             /* do the resampling, i.e., actually play sounds */
  142.         for (i = 0; i < number; i++) 
  143.             {
  144.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  145.                 {
  146.                 ch = chan + channel;
  147.                 switch(ch->mode)
  148.                     {
  149.                 case DO_NOTHING:
  150.                     byte[channel] = 0;
  151.                     break;
  152.                 case PLAY:
  153.                         /* Since we now have fix_length, we can
  154.                          * do that check with improved performance
  155.                          */
  156.                     if (ch->pointer < ch->samp->fix_length)
  157.                         {
  158.                         byte[channel] = ch->samp->start[C] * ch->volume;
  159.                         ch->pointer += ch->step;
  160.                         break;
  161.                         }
  162.                     else
  163.                         {
  164.                         ch->mode = REPLAY;
  165.                         ch->pointer -= ch->samp->fix_length;
  166.                         }
  167.                 case REPLAY:
  168.                             /* is there a replay ? */
  169.                     if (!ch->samp->rp_start)
  170.                         {
  171.                         ch->mode = DO_NOTHING;
  172.                         break;
  173.                         }
  174.                     while (ch->pointer >= ch->samp->fix_rp_length)
  175.                         ch->pointer -= ch->samp->fix_rp_length;
  176.                     byte[channel] = ch->samp->rp_start[C] * ch->volume;
  177.                     ch->pointer += ch->step;
  178.                     break;
  179.                     }
  180.                 } 
  181.             output_samples(byte[0]+byte[3], byte[1]+byte[2]);
  182.             }
  183.         }   
  184.     else
  185.         {
  186.             /* do the resampling, i.e., actually play sounds */
  187.         for (i = 0; i < number; i++) 
  188.             {
  189.             for (channel = 0; channel < NUMBER_TRACKS; channel++)
  190.                 {
  191.                 byte[channel] = 0;
  192.                 for (sampling = 0; sampling < oversample; sampling++)
  193.                     {
  194.                     ch = chan + channel;
  195.                     switch(ch->mode)
  196.                         {
  197.                     case DO_NOTHING:
  198.                         break;
  199.                     case PLAY:
  200.                             /* Since we now have fix_length, we can
  201.                              * do that check with improved performance
  202.                              */
  203.                         if (ch->pointer < ch->samp->fix_length)
  204.                             {
  205.                             sample = ch->samp->start[C];
  206.                             byte[channel] += sample * ch->volume;
  207.                             ch->pointer += ch->step;
  208.                             break;
  209.                             }
  210.                         else
  211.                             {
  212.                             ch->mode = REPLAY;
  213.                             ch->pointer -= ch->samp->fix_length;
  214.                             }
  215.                     case REPLAY:
  216.                                 /* is there a replay ? */
  217.                         if (!ch->samp->rp_start)
  218.                             {
  219.                             ch->mode = DO_NOTHING;
  220.                             break;
  221.                             }
  222.                         while (ch->pointer >= ch->samp->fix_rp_length)
  223.                             ch->pointer -= ch->samp->fix_rp_length;
  224.                         sample = ch->samp->rp_start[C];
  225.                         byte[channel] += sample * ch->volume;
  226.                         ch->pointer += ch->step;
  227.                         break;
  228.                         }
  229.                     } 
  230.                 }
  231.             output_samples((byte[0]+byte[3])/oversample, 
  232.                 (byte[1]+byte[2])/oversample);
  233.             }   
  234.         }
  235.  
  236.  
  237.     flush_buffer();
  238.     }
  239.  
  240. /*@ */
  241. #endif
  242.  
  243.  
  244. /* setting up a given note */
  245.  
  246. void reset_note(ch, note, pitch)
  247. struct channel *ch;
  248. int note;
  249. int pitch;
  250.     {
  251.     ch->pointer = 0;
  252.     ch->mode = PLAY;
  253.     ch->pitch = pitch;
  254.     ch->note = note;
  255.     ch->viboffset = 0;
  256.     set_current_pitch(ch, pitch);
  257.     }
  258.  
  259. /* changing the current pitch (value
  260.  * may be temporary, and not stored
  261.  * in channel pitch, for instance vibratos.
  262.  */
  263. void set_current_pitch(ch, pitch)
  264. struct channel *ch;
  265. int pitch;
  266.     {
  267.         /* save current pitch in case we want to change
  268.          * the step table on the run
  269.          */
  270.     ch->cpitch = pitch;
  271.     ch->step = step_table[pitch];
  272.     }
  273.  
  274. /* changing the current volume. You HAVE to get through
  275.  * there so that it will work on EVERY machine.
  276.  */
  277. void set_current_volume(ch, volume)
  278. struct channel *ch;
  279. int volume;
  280.     {
  281.     ch->volume = MAX(MIN(volume, MAX_VOLUME), MIN_VOLUME);
  282.     }
  283.  
  284.